package com.ruoyi.workflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.workflow.domain.CarPackageAudit;
import com.ruoyi.workflow.domain.ServiceItem;
import com.ruoyi.workflow.mapper.CarPackageAuditMapper;
import com.ruoyi.workflow.mapper.ServiceItemMapper;
import com.ruoyi.workflow.service.ICarPackageAuditService;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.workflow.constant.AuditConstant.*;

/**
 * 套餐信息Service业务层处理
 *
 * @author xiaodu
 * @date 2023-06-30
 */
@Service
public class CarPackageAuditServiceImpl extends ServiceImpl<CarPackageAuditMapper,CarPackageAudit> implements ICarPackageAuditService {
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private ServiceItemMapper serviceItemMapper;


    /**
     * 查询套餐信息列表
     *
     * @param carPackageAudit 套餐信息
     * @return 套餐信息
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit) {
        return carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
    }


    /**
     * 根据id查询流程进度
     *
     * @param id
     * @return
     */
    //方案2：根据历史service查出审核所经历的节点高亮
    @Override
    public InputStream readProcessImg(Long id) {
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(id,Collections.EMPTY_MAP);
        String instanceId = carPackageAudit.getInstanceId();

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        HistoryService historyService = processEngine.getHistoryService();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
        if(processInstance == null){
            throw new ServiceException("流程已结束!");
        }
        List<String> highLightedActivities = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId).list()
                .stream().map(item -> item.getActivityId()).collect(Collectors.toList());
        /**
         * bpmnModel- bpmn模型获取
         * highlightedactivity -用于指定需要高亮显示的活动节点ID（例如正在执行的任务）
         * highLightedFlows -用于指定需要高亮显示的连线ID（例如正在进行的流转路径）
         * activityFontName -覆盖默认活动字体
         * labelFontName -覆盖默认标签字体
         */
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        InputStream in = generator.generateDiagram(
                repositoryService.getBpmnModel(processInstance.getProcessDefinitionId()),
                highLightedActivities,
                Collections.EMPTY_LIST,
                "宋体",
                "宋体",
                "宋体"
        );
        return in;
    }


//    方案1：只显示当前审核的节点高亮，用运行service获取，并且审核结束查历史service,且不高亮
//    @Override
//    public InputStream readProcessImg(Long id) {
//        //根据流程实例查询审核状态
//        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(id);
//        String instanceId = carPackageAudit.getInstanceId();
//
//        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        RuntimeService runtimeService = processEngine.getRuntimeService();
//        RepositoryService repositoryService = processEngine.getRepositoryService();
//        HistoryService historyService = processEngine.getHistoryService();
//        InputStream in = null;
//        BpmnModel bpmnModel = null;
//        List<String> highLightedActivities = null;
//        String processDefinitionId = null;
//
//        //注意：情况1：审核流程结束，从historyService中获取
//        //      情况2：审核流程进行中，从runtimeService中获取
//        //审核中
//        if (SI_AUDIT_STATUS_REVIEW.equals(carPackageAudit.getStatus())) {
//            //1.根据流程实例ID，查询流程部署的ID
//            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
//            //2.根据流程部署ID，获取 .bpmn流程文件
//            processDefinitionId = processInstance.getProcessDefinitionId();
//            //3.根据流程实例ID，通过RuntimeService查询当前审核的任务节点
//            highLightedActivities = runtimeService.getActiveActivityIds(instanceId);
//
//        }else{
//            //审核流程完成，不需要高亮
//            //1.根据流程实例ID，查询流程部署的ID
//            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult();
//            //2.获取 .bpmn流程文件
//            processDefinitionId = historicProcessInstance.getProcessDefinitionId();
//            //3.审核流程完成，不需要高亮
//            highLightedActivities = Collections.EMPTY_LIST;
//        }
//        //4.获取 .bpmn流程文件
//        bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//        //5.生成流程文件 svg图，并且要高亮 当前审核的任务节点
//        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
//        in = generator.generateDiagram(
//                bpmnModel,
//                highLightedActivities,
//                Collections.EMPTY_LIST,
//                "宋体",
//                "宋体",
//                "宋体"
//        );
//        return in;
//    }

    /**
     * 撤销审核流程
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancelProcess(Long id,String reason) {
        //1.根据id查询服务项的id，根据服务项id把服务项中该套餐的审核状态：审核中---改为---> 初始化
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(id,Collections.EMPTY_MAP);
        if(carPackageAudit == null){
            throw new ServiceException("非法操作！");
        }
        //当前状态必须是审核中，才能撤销
        if(!(SI_AUDIT_STATUS_REVIEW.equals(carPackageAudit.getStatus()))){
            throw new ServiceException("状态错误，只有正在进行中的审核才可以撤销");
        }
        ServiceItem serviceItem = new ServiceItem();
        serviceItem.setId(carPackageAudit.getServiceItemId());
        serviceItem.setAuditStatus(SI_AUDIT_STATUS_INIT);
        int updateCount = serviceItemMapper.updateServiceItem(serviceItem);
        if (updateCount == 0) {
            throw new ServiceException("【撤销审核流程】：审核状态更新失败");
        }

        //2.根据id,把审核记录的状态修改为撤销申请
        CarPackageAudit updateCarPackageAudit = new CarPackageAudit();
        updateCarPackageAudit.setId(id);
        updateCarPackageAudit.setStatus(SI_AUDIT_STATUS_REVOKED);
        int delCount = carPackageAuditMapper.updateCarPackageAudit(updateCarPackageAudit);
        if (delCount == 0) {
            throw new ServiceException("【撤销审核流程】：审核套餐撤销失败");
        }

        //3.删除流程实例
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.deleteProcessInstance(carPackageAudit.getInstanceId(), reason);
    }

    /**
     * 审批历史
     * @param instanceId 流程实例
     * @return
     */
    @Override
    public List<Map<String, Object>> historyProcess(String instanceId){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        TaskService taskService = processEngine.getTaskService();
        List<HistoricActivityInstance> historyList = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId).list();
        if(historyList == null && historyList.size() == 0){
            throw new ServiceException("该流程实例无审批历史");
        }
        List<Map<String, Object>> mapList = historyList.stream().map(item -> {
//        任务名称
            String activityName = item.getActivityName();
//        开始时间
            Date startTime = item.getStartTime();
//        结束时间
            Date endTime = item.getEndTime();

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String startTimeStr = "";
            String endTimeStr = "";
            if(startTime != null){
                startTimeStr = dateFormat.format(startTime);
            }
            if(endTime != null){
                endTimeStr = dateFormat.format(endTime);
            }
//        耗时
            String datePoor = "";
            if(startTime != null && endTime != null){
                Date date = DateUtils.parseDate(dateFormat.format(startTime));
                Date date2 = DateUtils.parseDate(dateFormat.format(endTime));
                datePoor = DateUtils.getDatePoor(date, date2);
            }

//        审批人
            String assignee = item.getAssignee();
            if(assignee == null){
                assignee = "";
            }
//        审批意见
            String message = "";
            List<Comment> taskComments = Collections.EMPTY_LIST;
            if(item.getTaskId() != null){
                taskComments = taskService.getTaskComments(item.getTaskId());
            }
            if (taskComments.size() > 0) {
                message = taskComments.get(0).getFullMessage();
            }
//          撤销原因
            String reason = item.getDeleteReason();
            Map<String, Object> map = new HashMap<>();
            map.put("activityName", activityName);
            map.put("startTime", startTimeStr);
            map.put("endTime", endTimeStr);
            map.put("datePoor", datePoor);
            map.put("assignee", assignee);
            map.put("message", message);
            map.put("reason", reason);
            return map;
        }).collect(Collectors.toList());
        return mapList;
    }

    /**
     * 修改套餐审核表单 -- 套餐信息
     * @param serviceItem 封装申请的数据
     * @param auditId 套餐信息的ID
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateFormCarPackageAudit(ServiceItem serviceItem, Long auditId) {
        //根据auditId查询套餐信息
        CarPackageAudit oldObj = this.getById(auditId);
        //只有审核被拒绝的状态，才能进行表单修改，否则为 非法操作
        //根据套餐信息，判断状态 -> 拒绝 即可修改表单
        if(!SI_AUDIT_STATUS_OUT.equals(oldObj.getStatus())){
            throw new ServiceException("非法操作!");
        }

        //把拒绝改为 调整申请 SI_AUDIT_STATUS_READJUST
        super.update(new LambdaUpdateWrapper<CarPackageAudit>()
                .set(CarPackageAudit::getServiceItemName,serviceItem.getName())
                .set(CarPackageAudit::getServiceItemPrice,serviceItem.getDiscountPrice())
                .set(CarPackageAudit::getServiceItemInfo,serviceItem.getInfo())
                .set(CarPackageAudit::getStatus,SI_AUDIT_STATUS_READJUST)
                .eq(CarPackageAudit::getId,auditId));
    }

}
